package com.zusmart.base.network.handler.support;

import java.io.IOException;

import com.zusmart.base.buffer.Buffer;
import com.zusmart.base.handler.support.AbstractHandlerChain;
import com.zusmart.base.network.ChannelContext;
import com.zusmart.base.network.handler.ChannelContextHandler;
import com.zusmart.base.network.handler.ChannelContextHandlerChain;
import com.zusmart.base.network.handler.ChannelContextHandlerContext;
import com.zusmart.base.network.message.Message;
import com.zusmart.base.util.Assert;

public class DefaultChannelContextHandlerChain extends AbstractHandlerChain<ChannelContextHandler, ChannelContextHandlerContext, ChannelContextHandlerChain> implements ChannelContextHandlerChain {

	private final ChannelContext channelContext;

	public DefaultChannelContextHandlerChain(ChannelContext channelContext) {
		Assert.isNull(channelContext, "channel context must not be null");
		this.channelContext = channelContext;
	}

	@Override
	public ChannelContext getChannelContext() {
		return this.channelContext;
	}

	@Override
	public void fireOnRegister() {
		ChannelContextHandlerContext context = this.getFirstHandlerContext();
		if (null != context) {
			context.getHandler().onRegister(this.channelContext, context);
		}
	}

	@Override
	public void fireUnRegister() {
		ChannelContextHandlerContext context = this.getFirstHandlerContext();
		if (null != context) {
			context.getHandler().unRegister(this.channelContext, context);
		}
	}

	@Override
	public void fireOnMessage(Message message) {
		ChannelContextHandlerContext context = this.getFirstHandlerContext();
		if (null != context) {
			context.getHandler().onMessage(this.channelContext, context, message);
		}
	}

	@Override
	public void fireOnException(Throwable cause) {
		ChannelContextHandlerContext context = this.getFirstHandlerContext();
		if (null != context) {
			context.getHandler().onException(this.channelContext, context, cause);
		}
	}

	@Override
	public void fireOnTimeout() {
		ChannelContextHandlerContext context = this.getFirstHandlerContext();
		if (null != context) {
			context.getHandler().onTimeout(this.channelContext, context);
		}
	}

	@Override
	public void fireOnReader(Buffer buffer) throws IOException {
		ChannelContextHandlerContext context = this.getFirstHandlerContext();
		if (null != context) {
			context.getHandler().onReader(this.channelContext, context, buffer);
		}
	}

	@Override
	protected ChannelContextHandlerContext createHeadHandlerContext() {
		return new DefaultChannelContextHandlerContext(this, "__HEAD__", new DefaultChannelContextHandler());
	}

	@Override
	protected ChannelContextHandlerContext createFootHandlerContext() {
		return new DefaultChannelContextHandlerContext(this, "__FOOT__", new DefaultChannelContextHandler());
	}

	@Override
	protected ChannelContextHandlerContext createHandlerContext(String name, ChannelContextHandler handler) {
		return new DefaultChannelContextHandlerContext(this, name, handler);
	}

	///////////////////////////////////////////////////////////////////////////////////////

}